package EjerciciosFinal.ejerciciosFinal;

import java.util.LinkedList;
import java.util.List;

public class ConjuntoConTablaDeHash<T> implements Conjunto<T>{

	private List<T>[]tabla;
	
	public ConjuntoConTablaDeHash(){
		this.tabla = new LinkedList[20];
	}

	@Override
	public void agregar(T elemento) {
		int posicion = this.calcularCodigo(elemento);
		do{
			this.agrandarTabla();
		}while(this.tabla.length < posicion);
		
		if(this.tabla[posicion] == null){
			this.tabla[posicion] = new LinkedList<T>();
			this.tabla[posicion].add(elemento);
		}else{
			if((!this.tabla[posicion].contains(elemento))){
				this.tabla[posicion].add(elemento);
			}
		}
	}

	private void agrandarTabla() {
		int tamaño = this.tabla.length * 2;
		List<T>[]nuevaTabla = new LinkedList[tamaño];
		this.pasarElementosEntreTablas(nuevaTabla);
		this.tabla = nuevaTabla;
	}

	private void pasarElementosEntreTablas(List<T>[] nuevaTabla) {
		List<T> listaActual = null;
		for(int i = 0; i < this.tabla.length; i++){
			listaActual = this.tabla[i];
			if(listaActual != null){
				nuevaTabla[i].addAll(listaActual);
			}
		}
	}

	@Override
	public boolean estaVacio() {
		return (this.tabla.length < 0);
	}

	@Override
	public void limpiar() {
		for(int i = 0; i < this.tabla.length; i++){
			this.tabla[i] = null;
		}
	}

	@Override
	public int longitud() {
		int longitudTotal = 0;
		for(int i = 0; i < this.tabla.length; i++){
			if(this.tabla[i] != null){
				longitudTotal = longitudTotal + this.tabla[i].size();
			}
		}
		return longitudTotal;
	}

	@Override
	public void remover(T elemento) {
		int posicion = this.calcularCodigo(elemento);
		if((this.tabla[posicion] != null) && 
		   (this.tabla[posicion].contains(elemento))){
			
			this.tabla[posicion].remove(elemento);
		}
	}
	
	private int calcularCodigo(T elemento){
		return Math.abs(elemento.hashCode()/(this.tabla.length*1000000));
	}
}
